
#include <stdio.h>
#include <string.h>




GW_RS485 *com_hmi;
GW_RS485 *com_transmit;
GW_ModProtocol pol_HMIM;
GW_ModProtocol pol_Transmit;
GW_74HC595 relay_595;
GW_typ_Channel channels[CONF_MAXCHANNELS+1];
u16  oldprotocol[32][3];
u8 tmpbuf[10];
multimap<u16, pair<u16, int> > com_bus;
GW_RelayControl relayControl[3];
//multimap<u16,int> com_bus;
vector<int> com_gw;

//vector<GW_typ_Channel>



void USER_PWM_SetDutyRatio(TIM_HandleTypeDef *htim,uint32_t Channel,uint8_t value)  
{  
    TIM_OC_InitTypeDef sConfigOC;  
      
    uint32_t period=htim->Init.Period+1;  
    uint32_t pluse=(value * period)/100;  
      
    sConfigOC.OCMode = TIM_OCMODE_PWM1;  
    sConfigOC.Pulse = pluse;  
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;  
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;  
    HAL_TIM_PWM_ConfigChannel(htim, &sConfigOC, Channel);  
    HAL_TIM_PWM_Start(htim, Channel);     
}  

//void WriteComm(u16 CMD)
//{
//   *(__IO u16 *)(Bank1_LCD_C) = CMD;
//}
//void WriteData(u16 tem_data)
//{
//   *(__IO u16 *)(Bank1_LCD_D) = tem_data;
//}


WM_HWIN page_mnpage;
WM_HWIN page_summary;
WM_HWIN page_main;
WM_HWIN page_list;
WM_HWIN page_edit;
WM_HWIN wm_selcet;
WM_HWIN page_history;



WM_HTIMER tim_main;

u32 lcdid = 0;


void loadProtocol()
{
   int i = 0;
   for (i = 0; i < CONF_MAXCHANNELS; i++)
   {
      MEM.MEM32.protocol[i][0] = SYSMEM.SaveData.ChannelInfo[i].protocol;
      MEM.MEM32.protocol[i][1] = i + 1;
   }
   protocolChanged();
}

void task_do_default()
{

   GW_typ_History event; int x = 0,ret=0;
   struct tm set_time,*local_time;
   time_t time_dat;
   com_hmi = new GW_RS485(&huart1, &htim6, &hdma_usart1_rx, &Sem_HMICOMHandle);
   com_transmit = new GW_RS485(&huart5, &htim8, NULL, &Sem_TransmitHandle);
   HMIRECV;
   com_hmi->enableIT();
   com_transmit->enableIT();
   

   HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
   USER_PWM_SetDutyRatio(&htim3,TIM_CHANNEL_1,80);
   HAL_Delay(200);
   
   historyInit(&WriteHistory);
   historyInit(&ReadHistory);
   
   set_time.tm_sec = 10;
   set_time.tm_min = 0;
   set_time.tm_hour = 8;
   set_time.tm_mday = 13;
   set_time.tm_mon = 10-1;
   set_time.tm_year = 2017-1900;
   //set_time.tm_wday = 1;
   //set_time.tm_yday = 2;
   set_time.tm_isdst = -1;
   time_dat = mktime(&set_time);
   local_time = localtime(&time_dat);

   
   
   loadStore(ADDR_FLASH_PAGE_CONFIG, SYSMEM.SaveData_Buf, sizeof(SYSMEM));
   if (SYSMEM.SaveData.vaildcode!=VAILDCODE_CONFIG)
   {
      channels_DeInit();
      saveSYSMEM();
   }

   relayControl[0].setMark(&MEM.MEM32.RELAY1);
   relayControl[1].setMark(&MEM.MEM32.RELAY2);

   syncReadHistory(&ReadHistory, &WriteHistory);
   loadListChannel(channels, SYSMEM.SaveData.ChannelInfo);
   listView_All_Load(channels);
   loadProtocol();
   
   GUI_Init();
   GUI_Clear(); 


   //TOUCH_Cal_MainTask();
   wm_selcet=Createwm_select();
   page_mnpage = CreateFRM_MN();
   page_main=CreateFRM_Left();
   page_summary=CreateFRM_MAIN();
   tim_main=WM_CreateTimer(page_summary, 0, 1000, 0);


   WM_MESSAGE  myMsg;
   while (1)
   {
      GUI_TOUCH_Exec();
      GUI_Delay(2);

//    myMsg.MsgId=WM_MSG_TOUCH;
//    WM_SendMessage(win, &myMsg);

//	  osDelay(500);
//	  HAL_GPIO_TogglePin(LED_LO_GPIO_Port, LED_LO_Pin);
	  
//	  osDelay(10);
   }
}
u16 outbuf[64] = { -1, 0, -1 };
void task_do_HMI()
{
   int cnt = 0;
   int changed = 0;
   bool res = false;
   while (1)
   {
	  osSemaphoreWait(Sem_HMICOMHandle, osWaitForever);
	  cnt = com_hmi->recvCount();
	  if (cnt > 0)
	  {
		 res = pol_HMIM.Matching(cnt, com_hmi->recvbuf, CGlobal::addr, DIR_REQUEST);
		 if (res == true)
		 {
			HAL_GPIO_WritePin(LED_OK_GPIO_Port, LED_OK_Pin, GPIO_PIN_SET);
			switch (pol_HMIM.GetFunctionID())
			{
			case MODBUS_WRITEHOLD:
			   {
				  pol_HMIM.Recved(MEM.MEM32_Buf, sizeof(MEM), CGlobal::addr);
				  com_hmi->write(pol_HMIM.sendbuf, pol_HMIM.sendLength);
				  changed = memcmp(MEM.MEM32.protocol, oldprotocol, sizeof(oldprotocol));
				  if (changed != 0)
				  {
					 memcpy(oldprotocol, MEM.MEM32.protocol, sizeof(oldprotocol));
					 protocolChanged();
				  }
				  osTimerStart(myTimerWatchHMIHandle, 100);
				  break;
			   }
			case MODBUS_INPUTREG:
			   {
				  pol_HMIM.Recved((u8 *)outbuf, 64, CGlobal::addr);
				  com_hmi->write(pol_HMIM.sendbuf, pol_HMIM.sendLength);
				  osTimerStart(myTimerWatchHMIHandle, 100);
				  break;
			   }
			}
		 }
		 //osDelay(10);
		 //HAL_GPIO_WritePin(LED_OK_GPIO_Port, LED_OK_Pin, GPIO_PIN_RESET);
	  }
     GUI_Delay(50);
   }
}

void task_do_warn()
{
   u8 relayval = 0;
   relay_595.write(&relayval, 1);
   while (1)
   {
	  if (MEM.MEM32.BELLLo == 0 && MEM.MEM32.BELLHI == 0)
	  {
		 HAL_GPIO_WritePin(Bell_GPIO_Port, Bell_Pin, GPIO_PIN_RESET);
		 osDelay(1000);
	  }
	  //else if (relayValue[1] != 0)
	  else if (MEM.MEM32.BELLHI != 0)
	  {
		 HAL_GPIO_TogglePin(Bell_GPIO_Port, Bell_Pin);
		 osDelay(300);
	  }
	  //else if (relayValue[0] != 0)
	  else if (MEM.MEM32.BELLLo != 0)
	  {
		 HAL_GPIO_TogglePin(Bell_GPIO_Port, Bell_Pin);
		 osDelay(500);
	  }
	  //osDelay(10);
          //GUI_TOUCH_Exec(); 
     //GUI_Exec();
	  if (MEM.MEM32.RELAY1 != 0)
	  {
		 relayval |= VALRELAY1;
		 //HAL_GPIO_WritePin(Relay1_GPIO_Port, Relay1_Pin, GPIO_PIN_SET);
	  }
	  else
	  {
		 relayval &= ~VALRELAY1;
		 //HAL_GPIO_WritePin(Relay1_GPIO_Port, Relay1_Pin, GPIO_PIN_RESET);
	  }
	  //if (relayValue[3] != 0)
	  if (MEM.MEM32.RELAY2 != 0)
	  {
		 relayval |= VALRELAY2;
		 //HAL_GPIO_WritePin(Relay2_GPIO_Port, Relay2_Pin, GPIO_PIN_SET);
	  }
	  else
	  {
		 relayval &= ~VALRELAY2;
		 //HAL_GPIO_WritePin(Relay2_GPIO_Port, Relay2_Pin, GPIO_PIN_RESET);
	  }
	  relay_595.write(&relayval, 1);
     GUI_Delay(100);
   }
}
double testval = -11;
void task_do_Transmit()
{
   int cnt = 0, i = 0, tmp = 0,warnid=0;
   double tmpvalue = 0;
   bool res = false;
   GW_Data_Interget recvValue;
   while (1)
   {
      //osSemaphoreWait(Sem_TransmitHandle, osWaitForever);
      //cnt = com_transmit->recvCount();


      testval+=1;


      //checkChannel(&channels[1], &SYSMEM.SaveData.ChannelInfo[0]);

      
//      for (i = 0; i < 32;i++)
//      {
//         channels[i + 1].value = 0;
//         channels[i + 1].isChange = true;
//         //channels[1].isChange = true;
//         channels[1].value = testval;
//         checkChannel(&channels[i+1], &SYSMEM.SaveData.ChannelInfo[i]);
//         if (channels[i + 1].stateId == STATE_WARNLO)
//         {
//            if (SYSMEM.SaveData.ChannelInfo[i].relayLo & RELAY_1)
//            {
//               warnid = 0;
//            }
//            else if (SYSMEM.SaveData.ChannelInfo[i].relayLo & RELAY_2)
//            {
//               warnid = 1;
//            }
//            else if (SYSMEM.SaveData.ChannelInfo[i].relayLo & RELAY_3)
//            {
//               warnid = 2;
//            }
//            relayControl[warnid].enableRelay(i);
//         }
//         else if (channels[i + 1].stateId == STATE_WARNHI)
//         {
//            if (SYSMEM.SaveData.ChannelInfo[i].relayHi & RELAY_1)
//            {
//               warnid = 0;
//            }
//            else if (SYSMEM.SaveData.ChannelInfo[i].relayHi & RELAY_2)
//            {
//               warnid = 1;
//            }
//            else if (SYSMEM.SaveData.ChannelInfo[i].relayHi & RELAY_3)
//            {
//               warnid = 2;
//            }
//            relayControl[warnid].enableRelay(i);
//         }
//         else if (channels[i + 1].stateId == STATE_OK)
//         {
//            relayControl[0].disableRelay(i);
//            relayControl[1].disableRelay(i);
//            relayControl[2].disableRelay(i);
//         }
//
//      }
//
//      listView_All_Refresh();
//
//      GUI_Delay(100*5);

      
    if (!com_gw.empty())
    {
       cnt = com_gw.size();
       if (cnt > CONF_MAXCHANNELS)
       {
          continue;
       }
       for (i = 0; i < cnt; i++)
       {
          pol_Transmit.Poll(com_gw[i], MODBUS_BB);
          com_transmit->write(pol_Transmit.sendbuf, pol_Transmit.sendLength);
          //com_transmit->recvStart();
          //com_transmit->enableIT();
          if (osSemaphoreWait(Sem_TransmitHandle, 300) == osOK)
          {
             res = pol_Transmit.Matching(com_transmit->recvCount(), com_transmit->recvbuf, com_gw[i], DIR_REPONSE);
             if (res == true)
             {
                pol_Transmit.DataLoaded(recvValue.Interget_Buf, 2, MODBUS_BB);
                tmp = BigLittleSwap32(recvValue._Interget.data);
                tmpvalue = tmp / 100;
                outbuf[com_gw[i]] = tmp / 100;
                if (channels[com_gw[i]].value != tmpvalue)
                {
                   channels[com_gw[i]].isChange = true;
                   channels[com_gw[i]].value = tmpvalue;
                   listView_All_Refresh();
                }
             }
             channels[com_gw[i]].Faild = 0;
             osDelay(200);
          }
          else
          {
             tmp = com_gw[i];
             if (channels[tmp].Faild >= 10) outbuf[com_gw[i]] = -1;
             else
                channels[tmp].Faild++;
          }
          com_transmit->clear();

       }
    }
    GUI_Delay(50);

   }
}

void timer_do_watchHMI()
{
   if (com_hmi->isWaiting)
   {
      HMIRECV;
      com_hmi->isWaiting = false;
   }
}

void protocolChanged()
{
   int i = 0;
   com_bus.clear();
   com_gw.clear();
   for (i = 0; i < CONF_MAXCHANNELS; i++)
   {
	  if (MEM.MEM32.protocol[i][0] != 0)
	  {
		 switch (MEM.MEM32.protocol[i][0])
		 {
		 case PROTOCOL_MODBUS:
			{
			   pair<u16, int> ch(MEM.MEM32.protocol[i][2], i);
			   pair<u16, pair<u16, int> > group(MEM.MEM32.protocol[i][1], ch);
			   com_bus.insert(group);
			   break;
			}
		 case PROTOCOL_GW:
			{
			   com_gw.push_back(MEM.MEM32.protocol[i][1]);
			   break;
			}
		 }
	  }
   }
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
   if (UartHandle == com_hmi->uart)
   {
	  com_hmi->beginRecv();
   }
   else if (UartHandle == com_transmit->uart)
   {
	  com_transmit->beginRecv();
   }
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   if (htim == com_hmi->tim)
   {
	  com_hmi->timeout();
   }
   else if (htim == com_transmit->tim)
   {
	  com_transmit->timeout();
	  //com_transmit->write(strbuf, 4);
   }
}

void * operator new(size_t size)
{
   void *mem;
   mem = pvPortMalloc(size);
   memset(mem, 0, size);
   if (mem == NULL)
   {
	  while (1)
	  {
		 ;
	  }
   }
   return mem;
}

void operator delete(void *p)
{
   vPortFree(p);
}


